<?php


namespace app\common\service;


use app\admin\model\order\Order;
use app\admin\model\order\OrderGoodsInfo;
use app\admin\model\store\Goods;
use app\admin\model\store\GoodsSku;
use app\admin\model\store\GoodsCoupon;
use app\admin\model\store\Pink;
use app\admin\model\store\PinkConfig;
use app\admin\model\user\User;
use app\common\service\lib\Pay\AliPay;
use app\common\service\store\SeckillConfigService;
use app\common\service\store\GoodsCouponService;
use app\common\service\user\BillService;
use Ar414\RedisLock;
use think\Exception;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;

class PayService extends BaseService
{
    /**
     * Author:YangXinPeng
     * 支付宝支付
     * @param $params
     * @return mixed|\Symfony\Component\HttpFoundation\Response
     */
    public static function pay($params)
    {
        $pay = new AliPay();
        return $pay->doAction($params);
    }

    /**
     * Author:YangXinPeng
     * 支付宝退款
     * @param $params
     * @return array
     */
    public static function refund($params)
    {
        $pay = new AliPay();
        return $pay->refund($params);
    }

    /**
     * Author:YangXinPeng
     * 支付宝查询
     * @param $params
     */
    public static function find($params)
    {
        $pay = new AliPay();
        $pay->find($params);
    }

    /**
     * Author:YangXinPeng
     * 余额支付
     * @param $params
     * @throws Exception
     */
    public static function balancePay($params)
    {
        $redis = Cache::store('redis');
        $redis->select(6);
        $lockTimeOut = 5;
        $redisLock = new RedisLock($redis, $lockTimeOut);
        $lockKey = config('setting.blance');
        $lockExpire = $redisLock->getLock($lockKey);
        $pm = 0;
        $type = "yue";
        $title = "余额支付";
        $order = Order::where('order_no', $params['order_no'])->find();
        if ($lockExpire) {
            try {
                $userBalance = User::where('id', $params['uid'])->value('money');
                $price = $params['pay_price'];
                if ($userBalance >= $price) {
                    $newUserBalance = bcsub($userBalance, $price);
                    $flag = User::where('id', $params['uid'])->update(['money' => $newUserBalance]);
                    if ($flag) {
                        //修改订单状态
                        Db::startTrans();
                        try {
                            if ($order['pink_id'] != 0) {
                                $count = Order::where('pink_no', $order['pink_no'])->count();
                                $pinkPeople = PinkConfig::where('id', $order['pink_id'])->value('pink_people');
                                if ($pinkPeople == $count) {
                                    Order::where('pink_no', $order['pink_no'])
                                        ->update(['is_pink_status' => 1]);
                                }
                            }
                            Order::where('order_no', $params['order_no'])
                                ->update(['pay_status' => 1, 'status' => 1, 'pay_time' => time(), 'pay_type' => 3]);
                            BillService::createBill($order, $pm, $type, $title);
                            // 提交事务
                            Db::commit();
                            $redisLock->releaseLock($lockKey, $lockExpire);
                            return self::success('余额支付成功');
                        } catch (\Exception $e) {
                            // 回滚事务
                            Db::rollback();
                            return self::fail('未知错误');
                        }
                    }
                } else {
                    Db::startTrans();
                    try {
                        $surplus = bcsub($price, $userBalance);
                        User::where('id', $params['uid'])->update(['money' => 0]);
                        Order::where('order_no', $params['order_no'])
                            ->update(['pay_status' => 2, 'status' => 0, 'pay_time' => time(), 'pay_type' => 3]);
                        BillService::createBill($order, $pm, $type, $title);
                        // 提交事务
                        Db::commit();
                        $redisLock->releaseLock($lockKey, $lockExpire);
                        return self::fail(
                            '用户余额不足，可以选择支付宝继续支付',
                            ['index' => 0, 'price' => $surplus],
                            403
                        );
                    } catch (\Exception $e) {
                        // 回滚事务
                        Db::rollback();
                        return self::fail('未知错误');
                    }
                }
            } catch (\Throwable $throwable) {
                $redisLock->releaseLock($lockKey, $lockExpire);
                return self::fail('网络繁忙');
            }
        }
    }

    /**
     * Author:YangXinPeng
     * 异常订单轮询处理 防止掉单
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function turnCheckOrder()
    {
        $pay = new AliPay();
        $orders = Order::where('status', 4)->select();
        $orders && $orders = $orders->toArray();
        foreach ($orders as $value) {
            $res = $pay->find($value['order_id']);
            if ($res['trade_status'] == 'TRADE_SUCCESS') {
                $info = OrderGoodsInfo::where('oid', $res['out_trade_no'])->value('cart_info');
                $data = json_decode($info, true);
                $type = 1;
                Db::startTrans();
                try {
                    Order::where('order_id', $res['out_trade_no'])
                        ->update(['paid' => 1, 'status' => 0, 'pay_time' => time(), 'pay_type' => 'alipay']);
                    foreach ($data as $v) {
                        $skuId = $v['id'];
                        $goodId = $v['good']['id'];
                        $num = $v['cart_num'];
                        GoodsSku::where('id', $skuId)->dec('goods_stock', $num)->update();
                        Goods::where('id', $goodId)->dec('goods_stock', $num)->update();
                    }
                    BillService::createBill($value, $type);
                    // 提交事务
                    Db::commit();
                } catch (\Exception $e) {
                    // 回滚事务
                    Db::rollback();
                    $pay->refund($value['order_id']);
                }
            }
        }
    }


}